home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 3 / Cream of the Crop 3.iso / comm / wnos5src.zip / PATHNAME.C < prev    next >
C/C++ Source or Header  |  1993-10-03  |  3KB  |  130 lines

  1. #include <stdio.h>
  2. #include "global.h"
  3. #include "dirutil.h"
  4.  
  5. /* Process a path name string, starting with and adding to
  6.  * the existing buffer
  7.  */
  8. static void near
  9. crunch(char *buf,char *path)
  10. {
  11.     char *cp = buf + strlen(buf);    /* Start write at end of current buffer */
  12.  
  13.     /* Now start crunching the pathname argument */
  14.     for(;;){
  15.         /* Strip leading /'s; one will be written later */
  16.         while(*path == '/')
  17.             path++;
  18.  
  19.         /* no more, all done */
  20.         if(*path == '\0')
  21.             break;
  22.  
  23.         /* Look for parent directory references, either at the end
  24.          * of the path or imbedded in it
  25.          */
  26.         if(strcmp(path,"..") == 0 || strncmp(path,"../",3) == 0) {
  27.             /* Hop up a level */
  28.             if((cp = strrchr(buf,'/')) == NULLCHAR) {
  29.                 /* Don't back up beyond root */
  30.                 cp = buf;
  31.             }
  32.  
  33.             /* In case there's another .. */
  34.             *cp = '\0';
  35.  
  36.             /* Skip ".." */
  37.             path += 2;
  38.  
  39.             /* Skip one or more slashes */
  40.             while(*path == '/') {
  41.                 path++;
  42.             }
  43.         } else if(*path == '.' || strncmp(path,"./",2) == 0) {
  44.             /* "no op" */
  45.             /* Skip "." */
  46.             path++;
  47.  
  48.             /* Skip one or more slashes */
  49.             while(*path == '/')
  50.                 path++;
  51.         } else {
  52.             /* Ordinary name, copy up to next '/' or end of path */
  53.             *cp++ = '/';
  54.             while(*path != '/' && *path != '\0')
  55.                 *cp++ = *path++;
  56.         }
  57.     }
  58.     *cp++ = '\0';
  59. }
  60.  
  61. /* Given a working directory and an arbitrary pathname, resolve them into
  62.  * an absolute pathname. Memory is allocated for the result, which
  63.  * the caller must free
  64.  */
  65. char *
  66. pathname(char *cd,char *path)
  67. {
  68.     char *buf, *tbuf, *cp, c;
  69.     int tflag = 0;
  70.  
  71.     if(cd == NULLCHAR || path == NULLCHAR)
  72.         return NULLCHAR;
  73.  
  74.     /* If path has any backslashes, make a local copy with them
  75.      * translated into forward slashes
  76.      */
  77.     if(strchr(path,'\\') != NULLCHAR) {
  78.         tflag = 1;
  79.         cp = tbuf = mxallocw(strlen(path));
  80.         while((c = *path++) != '\0'){
  81.             if(c == '\\') {
  82.                 *cp++ = '/';
  83.             } else {
  84.                 *cp++ = c;
  85.             }
  86.         }
  87.         *cp = '\0';
  88.         path = tbuf;
  89.     }
  90.  
  91.     /* Strip any leading white space on args */
  92.     while(*cd == ' ' || *cd == '\t')
  93.         cd++;
  94.     while(*path == ' ' || *path == '\t')
  95.         path++;
  96.  
  97.     /* Allocate and initialize output buffer; user must free */
  98.     buf = mxallocw(strlen(cd) + strlen(path) + 10);    /* fudge factor */
  99.  
  100.     /* Interpret path relative to cd only if it doesn't begin with "/" */
  101.     if(*path != '/')
  102.         crunch(buf,cd);
  103.  
  104.     crunch(buf,path);
  105.  
  106.     /* Special case: null final path means the root directory */
  107.     if(buf[0] == '\0') {
  108.         if(cd[1] == ':') {
  109.             strncpy(buf,cd,4);
  110.             buf[3] = '\0';
  111.         } else {
  112.             buf[0] = '/';
  113.             buf[1] = '\0';
  114.         }
  115.     }
  116.     if(tflag)
  117.         xfree(tbuf);
  118.  
  119.     if(buf[2] == ':') {
  120.         if(buf[3] == '\0') {
  121.             buf[3] = '/';
  122.             buf[4] = '\0';
  123.         }
  124.         cp = strxdup(&buf[1]);
  125.         xfree(buf);
  126.         buf = cp;
  127.     }
  128.     return buf;
  129. }
  130.